package com.itlong.cloud.oss.alibaba;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.google.common.io.Files;
import com.itlong.cloud.POJO.DTO.operate.OperateOSSCallBackDTO;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.operate.OperateOSSTokenVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.commons.dao.ICommonsDao;
import com.itlong.cloud.commons.dao.OperationSpecialLogDao;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.DeviceMediaInfoPublishStatusEnum;
import com.itlong.cloud.enumerate.PropertyEquipTypeEnum;
import com.itlong.cloud.enumerate.SmartCommunityEnum;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.file.UnGZipUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RefreshScope
public class AliOSSService {
    private static final Logger LOG = LoggerFactory.getLogger(AliOSSService.class);

    @Value("${" + PlatformConstants.ALIBABA_OSS_ENDPOINT + "}")
    public String ALIBABA_OSS_ENDPOINT;
    @Value("${" + PlatformConstants.ALIBABA_OSS_ACCESSID + "}")
    public String ALIBABA_OSS_ACCESSID;
    @Value("${" + PlatformConstants.ALIBABA_OSS_ACCESSKEY + "}")
    public String ALIBABA_OSS_ACCESSKEY;
    @Value("${" + PlatformConstants.ALIBABA_OSS_BUCKET + "}")
    public String ALIBABA_OSS_BUCKET;
    @Value("${" + PlatformConstants.ALIBABA_OSS_DIR + "}")
    public String ALIBABA_OSS_DIR;
    @Value("${" + PlatformConstants.ALIBABA_OSS_MEDIA_DIR + "}")
    public String ALIBABA_OSS_MEDIA_DIR;
    @Value("${" + PlatformConstants.ALIBABA_OSS_CALLBACKURL + "}")
    public String ALIBABA_OSS_CALLBACKURL;
    @Value("${" + PlatformConstants.ALIBABA_OSS_MEDIA_CALLBACKURL + "}")
    public String ALIBABA_OSS_MEDIA_CALLBACKURL;

    @Autowired
    ICommonsDao iCommonsDao;

    @Autowired
    MessageSender messageSender;

    @Autowired
    private OperationSpecialLogDao operationSpecialLogDao;

    /**
     * <desc>
     * 获取OSS上传凭证
     * </desc>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018/07/11
     */
    public OperateOSSTokenVO getOSSToken() {
        OSSClient ossClient = new OSSClient(ALIBABA_OSS_ENDPOINT, ALIBABA_OSS_ACCESSID, ALIBABA_OSS_ACCESSKEY);
        try {
            String host = ALIBABA_OSS_BUCKET + "." + ALIBABA_OSS_ENDPOINT.replace("http://", "");
            long expireTime = 30;//有效期30分钟
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000 * 60;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);//大小限制1G
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, ALIBABA_OSS_DIR);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);
            OperateOSSTokenVO operateOSSTokenVO = new OperateOSSTokenVO();
            operateOSSTokenVO.setAccessid(ALIBABA_OSS_ACCESSID);
            operateOSSTokenVO.setPolicy(encodedPolicy);
            operateOSSTokenVO.setSignature(postSignature);
            operateOSSTokenVO.setDir(ALIBABA_OSS_DIR);
            operateOSSTokenVO.setHost(host);
            operateOSSTokenVO.setExpire(String.valueOf(expireEndTime / 1000));
            operateOSSTokenVO.setBucket(ALIBABA_OSS_BUCKET);
            //operateOSSTokenVO.setCallbackHost(ALIBABA_OSS_ENDPOINT.replace("http://",""));
            operateOSSTokenVO.setCallbackUrl(ALIBABA_OSS_CALLBACKURL);
            operateOSSTokenVO.setRegion(ALIBABA_OSS_ENDPOINT.replace("http://", "").replace(".aliyuncs.com", ""));

            return operateOSSTokenVO;
        } catch (Exception e) {
            LOG.error("获取阿里OSS上传凭证失败！e:" + e.getMessage());
            return null;
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * <desc>
     * 获取阿里OSS通行证
     * <desc/>
     *
     * @return
     * @author wangzhi
     * @createDate 2018/11/22
     */
    public OperateOSSTokenVO getMediaOSSToken() {
        OSSClient ossClient = new OSSClient(ALIBABA_OSS_ENDPOINT, ALIBABA_OSS_ACCESSID, ALIBABA_OSS_ACCESSKEY);
        try {
            String host = ALIBABA_OSS_BUCKET + "." + ALIBABA_OSS_ENDPOINT.replace("http://", "");
            long expireTime = 30;//有效期30分钟
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000 * 60;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 2048576000);//大小限制2G
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, ALIBABA_OSS_MEDIA_DIR);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);
            OperateOSSTokenVO operateOSSTokenVO = new OperateOSSTokenVO();
            operateOSSTokenVO.setAccessid(ALIBABA_OSS_ACCESSID);
            operateOSSTokenVO.setPolicy(encodedPolicy);
            operateOSSTokenVO.setSignature(postSignature);
            operateOSSTokenVO.setDir(ALIBABA_OSS_MEDIA_DIR);
            operateOSSTokenVO.setHost(host);
            operateOSSTokenVO.setExpire(String.valueOf(expireEndTime / 1000));
            operateOSSTokenVO.setBucket(ALIBABA_OSS_BUCKET);
            //operateOSSTokenVO.setCallbackHost(ALIBABA_OSS_ENDPOINT.replace("http://",""));
            operateOSSTokenVO.setCallbackUrl(ALIBABA_OSS_MEDIA_CALLBACKURL);
            operateOSSTokenVO.setRegion(ALIBABA_OSS_ENDPOINT.replace("http://", "").replace(".aliyuncs.com", ""));

            return operateOSSTokenVO;
        } catch (Exception e) {
            LOG.error("获取阿里OSS上传凭证失败！e:" + e.getMessage());
            return null;
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * <desc>
     * OSS服务器回调业务处理
     * </desc>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018/07/11
     */
    public boolean OSSCallBack(OperateOSSCallBackDTO operateOSSCallBackDTO) {
        OSSClient ossClient = new OSSClient(ALIBABA_OSS_ENDPOINT, ALIBABA_OSS_ACCESSID, ALIBABA_OSS_ACCESSKEY);
        java.util.Date nowTime = new java.util.Date();
        try {
            boolean ret;
            byte[] authorization = BinaryUtil.fromBase64String(operateOSSCallBackDTO.getAutorizationInput());
            byte[] pubKey = BinaryUtil.fromBase64String(operateOSSCallBackDTO.getPubKeyInput());
            String pubKeyAddr = new String(pubKey);
            if (!pubKeyAddr.startsWith("http://gosspublic.alicdn.com/") && !pubKeyAddr.startsWith("https://gosspublic.alicdn.com/")) {
                LOG.info("============================pub key addr must be oss addrss");
                return false;
            }
            String retString = executeGet(pubKeyAddr);
            String queryString = operateOSSCallBackDTO.getQueryString();
            String decodeUri = java.net.URLDecoder.decode(operateOSSCallBackDTO.getUri(), "UTF-8");
            String authStr = decodeUri;
            if (queryString != null && !queryString.equals("")) {
                authStr += "?" + queryString;
            }
            String ossCallbackBody = operateOSSCallBackDTO.getOssCallbackBody();
            //LOG.info("===阿里回调接收的body值=======================》{}",ossCallbackBody);
            // 回调内容
            if (ossCallbackBody != null && !"".equals(ossCallbackBody)) {
                authStr += "\n" + ossCallbackBody;
                ret = doCheck(authStr, authorization, retString);
                if (ret) {
                    JSONObject res = new JSONObject(ossCallbackBody);
                    // 获取url设定过期时间
                    // 设置URL过期时间为3600秒*24小时*365天*89年。
                    // 有生之年 89年 阿里估计都没了 我也没了
                    java.util.Date expiration = new java.util.Date(new java.util.Date().getTime() + 1000L * 3600L * 24L * 365L * 89L);
                    // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
                    URL url = ossClient.generatePresignedUrl(ALIBABA_OSS_BUCKET, res.get("fileName").toString(), expiration);//下载url
                    LOG.info(url.toString());
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    // 设置超时间为3秒
                    conn.setConnectTimeout(3 * 1000);
                    // 防止屏蔽程序抓取而返回403错误
                    conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                    // 得到输入流
                    InputStream inputStream = conn.getInputStream();//取得流
                    if (inputStream != null) {//验证url是否可用
                        // 数据固化
                        String doTable = res.get("doTable").toString();
                        res.remove("fileName");
                        res.remove("doTable");
                        DeviceCloudUpdatePO deviceCloudUpdatePO = JsonUtil.toObject(res.toString(), DeviceCloudUpdatePO.class);
                        if ("%nodata%".equals(deviceCloudUpdatePO.getTypePid())) {
                            deviceCloudUpdatePO.setTypePid("");
                        }
                        if ("%nodata%".equals(deviceCloudUpdatePO.getRemark())) {
                            deviceCloudUpdatePO.setRemark("");
                        }
                        if ("%nodata%".equals(deviceCloudUpdatePO.getFilePackage())) {
                            deviceCloudUpdatePO.setFilePackage("");
                        }
                        if ("%nodata%".equals(deviceCloudUpdatePO.getVersion())) {
                            deviceCloudUpdatePO.setVersion("");
                        }
                        deviceCloudUpdatePO.setUpdateUrl(url.toString());
                        // LOG.info("===阿里回调存入的deviceCloudUpdatePO值=======================》{}",deviceCloudUpdatePO);
                        Map<String, Object> params = null;
                        if (doTable != null && "insert".equals(doTable)) {
                            //判断新增当时是否有重复的
                            if (StringUtils.isNotBlank(iCommonsDao.getUpdateInfoByName(deviceCloudUpdatePO.getUpdateName()))) {
                                return false;
                            }
                            deviceCloudUpdatePO.setUpdateId(LogicIdUtil.bussinessId());
                            deviceCloudUpdatePO.setCreateTime(new java.util.Date());
                            deviceCloudUpdatePO.setStatus(DataStatusEnum.NORMAL.getType());
                            deviceCloudUpdatePO.setUpdateTime(null);

                            params = SqlUtil.durableData(deviceCloudUpdatePO, PlatformConstants.TABLE_SAVE);

                        }
                        if (doTable != null && "update".equals(doTable)) {
                            deviceCloudUpdatePO.setUpdateTime(new java.util.Date());
                            params = SqlUtil.durableData(deviceCloudUpdatePO, PlatformConstants.TABLE_UPDATE);

                        }
                        for (String key : params.keySet()) {
                            if (params.get(key) != null && "".equals(params.get(key))) {
                                params.put(key, null);
                            }
                        }
                        int num = 0;
                        if (doTable != null && "insert".equals(doTable)) {
                            LOG.info("===阿里回调存入的params值=======================》{}", params.toString());
                            num = iCommonsDao.save(params);
                            //新增操作日志
                            OperateUserInfoPO operateUserInfoPO = operationSpecialLogDao.getOperateUserPO(deviceCloudUpdatePO.getUserId());
                            OperationSpecialLogPO operationSpecialLogPO = new OperationSpecialLogPO();
                            operationSpecialLogPO.setLogId(LogicIdUtil.bussinessId());
                            operationSpecialLogPO.setRealName(operateUserInfoPO.getRealName());
                            operationSpecialLogPO.setAccount(operateUserInfoPO.getUserName());
                            operationSpecialLogPO.setOuterId(deviceCloudUpdatePO.getUpdateId());
                            operationSpecialLogPO.setIp(operateOSSCallBackDTO.getIp());
                            operationSpecialLogPO.setOperateFunction(deviceCloudUpdatePO.getOperateFunction());
                            operationSpecialLogPO.setOperateWay(deviceCloudUpdatePO.getOperateWay());
                            operationSpecialLogPO.setFunctionType(7);
                            operationSpecialLogPO.setOperateDec(operateUserInfoPO.getRealName() + "在oss上，上传了" + deviceCloudUpdatePO.getUpdateName() + "安装包");
                            operationSpecialLogPO.setStatus(DataStatusEnum.NORMAL.getType());
                            operationSpecialLogPO.setCreateTime(nowTime);
                            operationSpecialLogPO.setUpdateTime(nowTime);
                            operationSpecialLogDao.save(SqlUtil.durableData(operationSpecialLogPO, PlatformConstants.TABLE_SAVE));
                            LOG.info("===阿里回调存入的operationSpecialLogDao值=======================》{}", operationSpecialLogPO.toString());


                        }
                        if (doTable != null && "update".equals(doTable)) {
                            LOG.info("===阿里回调修改存入的params值=======================》{}", params.toString());
                            num = iCommonsDao.update(params);
                            //新增操作日志
                            OperateUserInfoPO operateUserInfoPO = operationSpecialLogDao.getOperateUserPO(deviceCloudUpdatePO.getUserId());
                            OperationSpecialLogPO operationSpecialLogPO = new OperationSpecialLogPO();
                            operationSpecialLogPO.setLogId(LogicIdUtil.bussinessId());
                            operationSpecialLogPO.setRealName(operateUserInfoPO.getRealName());
                            operationSpecialLogPO.setAccount(operateUserInfoPO.getUserName());
                            operationSpecialLogPO.setOuterId(deviceCloudUpdatePO.getUpdateId());
                            operationSpecialLogPO.setIp(operateOSSCallBackDTO.getIp());
                            operationSpecialLogPO.setOperateFunction(deviceCloudUpdatePO.getOperateFunction());
                            operationSpecialLogPO.setOperateWay(deviceCloudUpdatePO.getOperateWay());
                            operationSpecialLogPO.setFunctionType(7);
                            operationSpecialLogPO.setOperateDec(operateUserInfoPO.getRealName() + "在oss上，替换了" + deviceCloudUpdatePO.getUpdateName() + "安装包");
                            operationSpecialLogPO.setStatus(DataStatusEnum.NORMAL.getType());
                            operationSpecialLogPO.setCreateTime(nowTime);
                            operationSpecialLogPO.setUpdateTime(nowTime);
                            operationSpecialLogDao.save(SqlUtil.durableData(operationSpecialLogPO, PlatformConstants.TABLE_SAVE));
                            LOG.info("===阿里回调修改存入的operationSpecialLogDao值=======================》{}", operationSpecialLogPO.toString());

                        }
                        inputStream.close();
                        if (num > 0) {
                            return true;
                        }
                        return false;
                    }
                }


            }
        } catch (Exception e) {
            e.printStackTrace();
            LOG.error("OSS回调处理失败！e:" + e.getMessage());
            return false;
        } finally {
            ossClient.shutdown();
        }
        return false;
    }

    /**
     * <desc>
     * OSS服务器回调业务处理
     * </desc>
     *
     * @return
     * @author wangzhi
     * @createDate 2018/11/22
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public boolean OSSMediaCallBack(OperateOSSCallBackDTO operateOSSCallBackDTO) {
        OSSClient ossClient = new OSSClient(ALIBABA_OSS_ENDPOINT, ALIBABA_OSS_ACCESSID, ALIBABA_OSS_ACCESSKEY);
        try {
            boolean ret;
            byte[] authorization = BinaryUtil.fromBase64String(operateOSSCallBackDTO.getAutorizationInput());
            byte[] pubKey = BinaryUtil.fromBase64String(operateOSSCallBackDTO.getPubKeyInput());
            String pubKeyAddr = new String(pubKey);
            if (!pubKeyAddr.startsWith("http://gosspublic.alicdn.com/") && !pubKeyAddr.startsWith("https://gosspublic.alicdn.com/")) {
                LOG.info("pub key addr must be oss addrss");
                return false;
            }
            String retString = executeGet(pubKeyAddr);
            String queryString = operateOSSCallBackDTO.getQueryString();
            String decodeUri = java.net.URLDecoder.decode(operateOSSCallBackDTO.getUri(), "UTF-8");
            String authStr = decodeUri;
            if (queryString != null && !queryString.equals("")) {
                authStr += "?" + queryString;
            }
            String ossCallbackBody = operateOSSCallBackDTO.getOssCallbackBody();
            LOG.info(ossCallbackBody);
            int num = 0;
            java.util.Date nowTime = new java.util.Date();
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1);
            // 回调内容
            if (ossCallbackBody != null && !"".equals(ossCallbackBody)) {
                authStr += "\n" + ossCallbackBody;
                ret = doCheck(authStr, authorization, retString);
                if (ret) {
                    JSONObject res = new JSONObject(ossCallbackBody);
                    // 获取url设定过期时间
                    // 设置URL过期时间为3600秒*24小时*365天*89年。
                    // 有生之年 89年 阿里估计都没了 我也没了
                    java.util.Date expiration = new java.util.Date(new java.util.Date().getTime() + 1000L * 3600L * 24L * 365L * 89L);
                    // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
                    URL url = ossClient.generatePresignedUrl(ALIBABA_OSS_BUCKET, res.get("fileName").toString(), expiration);//下载url
                    LOG.info(url.toString());
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    // 设置超时间为3秒
                    conn.setConnectTimeout(3 * 1000);
                    // 防止屏蔽程序抓取而返回403错误
                    conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                    // 得到输入流
                    InputStream inputStream = conn.getInputStream();//取得流
                    if (inputStream != null) {//验证url是否可用
                        // 数据固化
                        String doTable = res.get("doTable").toString();
                        res.remove("doTable");
                        res.remove("fileName");
                        if (doTable != null && "insert".equals(doTable)) {
                            DeviceMediaInfoSaveForBrowserDTO deviceMediaInfoSaveForBrowserDTO = JsonUtil.toObject(res.toString(), DeviceMediaInfoSaveForBrowserDTO.class);
                            DeviceMediaInfoPO deviceMediaInfoPO = new DeviceMediaInfoPO();
                            deviceMediaInfoPO.setMediaId(LogicIdUtil.bussinessId());
                            deviceMediaInfoPO.setAttacheFileUrl(url.toString());
                            deviceMediaInfoPO.setAttacheFile(deviceMediaInfoSaveForBrowserDTO.getAttacheFiles());
                            deviceMediaInfoPO.setAttacheFileMd5(deviceMediaInfoSaveForBrowserDTO.getAttacheFileMD5());
                            deviceMediaInfoPO.setProjectId(deviceMediaInfoSaveForBrowserDTO.getProjectId());
                            deviceMediaInfoPO.setTitle(deviceMediaInfoSaveForBrowserDTO.getTitle());
                            deviceMediaInfoPO.setType(deviceMediaInfoSaveForBrowserDTO.getType());
                            deviceMediaInfoPO.setEquipType(deviceMediaInfoSaveForBrowserDTO.getEquipType());
                            deviceMediaInfoPO.setPutStartTime(sdf.parse(deviceMediaInfoSaveForBrowserDTO.getPutStartTime()));
                            deviceMediaInfoPO.setPutEndTime(sdf.parse(deviceMediaInfoSaveForBrowserDTO.getPutEndTime()));
                            deviceMediaInfoPO.setPublishStatus(DeviceMediaInfoPublishStatusEnum.UN_CHECKED.getType());
                            deviceMediaInfoPO.setStatus(deviceMediaInfoSaveForBrowserDTO.getStatus());
                            deviceMediaInfoPO.setChildrenType(null);
                            deviceMediaInfoPO.setContent(null);
                            deviceMediaInfoPO.setCreateTime(nowTime);
                            deviceMediaInfoPO.setUpdateTime(nowTime);
                            Map<String, Object> params = SqlUtil.durableData(deviceMediaInfoPO, PlatformConstants.TABLE_SAVE);
                            num = iCommonsDao.save(params);
                            //分析多媒体资源绑定的地址和设备列表
                            if (StringUtils.isNotBlank(deviceMediaInfoSaveForBrowserDTO.getBindInfos())) {
                                List<DeviceMediaBindDTO> deviceMediaBindDTOS = null;
                                List<DeviceMediaBindAddressDTO> deviceMediaBindAddressDTOList = new ArrayList<>();
                                List<DeviceMediaBindDeviceDTO> deviceMediaBindDeviceDTOS = new ArrayList<>();
                                deviceMediaBindDTOS = iCommonsDao.getCloudIntercomInfo(StringHandlerUtil.splitStringList(deviceMediaInfoSaveForBrowserDTO.getBindInfos()));
                                // 遍历解析得到的绑定地址和设备列表
                                for (DeviceMediaBindDTO deviceMediaBindDTO : deviceMediaBindDTOS) {
                                    // 根据smartType属性判断是门口机还是围墙机
                                    if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(), 31)) {
                                        DeviceMediaBindAddressDTO deviceMediaBindAddressDTO = new DeviceMediaBindAddressDTO();
                                        deviceMediaBindAddressDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                                        deviceMediaBindAddressDTOList.add(deviceMediaBindAddressDTO);
                                    } else if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(), 32)) {
                                        DeviceMediaBindDeviceDTO deviceMediaBindDeviceDTO = new DeviceMediaBindDeviceDTO();
                                        deviceMediaBindDeviceDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                                        deviceMediaBindDeviceDTO.setSn(deviceMediaBindDTO.getSn());
                                        deviceMediaBindDeviceDTOS.add(deviceMediaBindDeviceDTO);
                                    }
                                }
                                List<Map<String, Object>> batchParams = new ArrayList<>();
                                if (!deviceMediaBindAddressDTOList.isEmpty()) {
                                    //批量保存门口机多媒体资源-服务地址关联信息
                                    batchParams.clear();
                                    for (DeviceMediaBindAddressDTO deviceMediaBindAddressDTO : deviceMediaBindAddressDTOList) {
                                        DeviceMediaGatePO deviceMediaGatePO = new DeviceMediaGatePO();
                                        deviceMediaGatePO.setMediaId(deviceMediaInfoPO.getMediaId());
                                        deviceMediaGatePO.setProjectId(deviceMediaInfoPO.getProjectId());
                                        deviceMediaGatePO.setDeviceUnique(deviceMediaBindAddressDTO.getDeviceUnique());
                                        deviceMediaGatePO.setCreateTime(deviceMediaInfoPO.getCreateTime());
                                        deviceMediaGatePO.setUpdateTime(deviceMediaInfoPO.getCreateTime());
                                        deviceMediaGatePO.setStatus(DataStatusEnum.NORMAL.getType());
                                        batchParams.add(SqlUtil.durableData(deviceMediaGatePO, PlatformConstants.TABLE_SAVE));
                                    }
                                    num += iCommonsDao.batchSaveGate(batchParams);
                                }
                                if (!deviceMediaBindDeviceDTOS.isEmpty()) {
                                    //批量保存围墙机多媒体资源-围墙机关联信息
                                    batchParams.clear();
                                    for (DeviceMediaBindDeviceDTO deviceMediaBindDeviceDTO : deviceMediaBindDeviceDTOS) {
                                        DeviceMediaWallPO deviceMediaWallPO = new DeviceMediaWallPO();
                                        deviceMediaWallPO.setMediaId(deviceMediaInfoPO.getMediaId());
                                        deviceMediaWallPO.setProjectId(deviceMediaInfoPO.getProjectId());
                                        deviceMediaWallPO.setDeviceUnique(deviceMediaBindDeviceDTO.getDeviceUnique());
                                        deviceMediaWallPO.setSn(deviceMediaBindDeviceDTO.getSn());
                                        deviceMediaWallPO.setCreateTime(deviceMediaInfoPO.getCreateTime());
                                        deviceMediaWallPO.setUpdateTime(deviceMediaInfoPO.getCreateTime());
                                        deviceMediaWallPO.setStatus(DataStatusEnum.NORMAL.getType());
                                        batchParams.add(SqlUtil.durableData(deviceMediaWallPO, PlatformConstants.TABLE_SAVE));
                                    }
                                    //保存围墙机关联信息
                                    num += iCommonsDao.batchSaveWall(batchParams);
                                }
                            }
                            //仅多媒体资源添加时设备类型为云对讲、状态为启用且发布状态为已发布时才通知云对讲更新
                            if (NumberHandlerUtil.isEqual(deviceMediaInfoPO.getEquipType(), PropertyEquipTypeEnum.CLOUD_INTERCOM.getType()) &&
                                    NumberHandlerUtil.isEqual(deviceMediaInfoPO.getStatus(), DataStatusEnum.NORMAL.getType()) &&
                                    NumberHandlerUtil.isEqual(deviceMediaInfoPO.getPublishStatus(), DeviceMediaInfoPublishStatusEnum.PUBLISHED.getType())) {
                                com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
                                jsonObject.put("projectId", deviceMediaInfoSaveForBrowserDTO.getProjectId());
                                DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                                        = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_MEDIA, jsonObject, deviceMediaInfoSaveForBrowserDTO.getProjectId());
                                List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
                                deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
                                com.alibaba.fastjson.JSONObject dataJs = new com.alibaba.fastjson.JSONObject();
                                dataJs.put("data", deviceBusinessChangeLogPOS);
                                messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                                        JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                                        RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                            }
                        }
                        if (doTable != null && "update".equals(doTable)) {
                            DeviceMediaInfoUpdateForBrowserDTO deviceMediaInfoUpdateForBrowserDTO = JsonUtil.toObject(res.toString(), DeviceMediaInfoUpdateForBrowserDTO.class);
                            DeviceMediaInfoPO deviceMediaInfoPO = new DeviceMediaInfoPO();
                            deviceMediaInfoPO.setMediaId(deviceMediaInfoUpdateForBrowserDTO.getMediaId());
                            deviceMediaInfoPO.setAttacheFileUrl(url.toString());
                            deviceMediaInfoPO.setAttacheFile(deviceMediaInfoUpdateForBrowserDTO.getAttacheFiles());
                            deviceMediaInfoPO.setAttacheFileMd5(deviceMediaInfoUpdateForBrowserDTO.getAttacheFileMD5());
                            deviceMediaInfoPO.setProjectId(null);
                            deviceMediaInfoPO.setTitle(deviceMediaInfoUpdateForBrowserDTO.getTitle());
                            deviceMediaInfoPO.setType(deviceMediaInfoUpdateForBrowserDTO.getType());
                            deviceMediaInfoPO.setEquipType(null);
                            deviceMediaInfoPO.setPutStartTime(sdf.parse(deviceMediaInfoUpdateForBrowserDTO.getPutStartTime()));
                            deviceMediaInfoPO.setPutEndTime(sdf.parse(deviceMediaInfoUpdateForBrowserDTO.getPutEndTime()));
                            deviceMediaInfoPO.setPublishStatus(DeviceMediaInfoPublishStatusEnum.UN_CHECKED.getType());
                            deviceMediaInfoPO.setStatus(deviceMediaInfoUpdateForBrowserDTO.getStatus());
                            deviceMediaInfoPO.setChildrenType(null);
                            deviceMediaInfoPO.setContent(null);
                            deviceMediaInfoPO.setUpdateTime(nowTime);
                            Map<String, Object> params = SqlUtil.durableData(deviceMediaInfoPO, PlatformConstants.TABLE_UPDATE);
                            num = iCommonsDao.update(params);
                            //分析多媒体资源绑定的地址和设备列表
                            if (StringUtils.isNotBlank(deviceMediaInfoUpdateForBrowserDTO.getBindInfos())) {
                                List<DeviceMediaBindDTO> deviceMediaBindDTOS = null;
                                List<DeviceMediaBindAddressDTO> deviceMediaBindAddressDTOList = new ArrayList<>();
                                List<DeviceMediaBindDeviceDTO> deviceMediaBindDeviceDTOS = new ArrayList<>();
                                deviceMediaBindDTOS = iCommonsDao.getCloudIntercomInfo(StringHandlerUtil.splitStringList(deviceMediaInfoUpdateForBrowserDTO.getBindInfos()));
                                // 遍历解析得到的绑定地址和设备列表
                                for (DeviceMediaBindDTO deviceMediaBindDTO : deviceMediaBindDTOS) {
                                    // 根据smartType属性判断是门口机还是围墙机
                                    if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(), 31)) {
                                        DeviceMediaBindAddressDTO deviceMediaBindAddressDTO = new DeviceMediaBindAddressDTO();
                                        deviceMediaBindAddressDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                                        deviceMediaBindAddressDTOList.add(deviceMediaBindAddressDTO);
                                    } else if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(), 32)) {
                                        DeviceMediaBindDeviceDTO deviceMediaBindDeviceDTO = new DeviceMediaBindDeviceDTO();
                                        deviceMediaBindDeviceDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                                        deviceMediaBindDeviceDTO.setSn(deviceMediaBindDTO.getSn());
                                        deviceMediaBindDeviceDTOS.add(deviceMediaBindDeviceDTO);
                                    }
                                }
                                List<Map<String, Object>> batchParams = new ArrayList<>();
                                iCommonsDao.removeGate(deviceMediaInfoPO.getMediaId());
                                iCommonsDao.removeWall(deviceMediaInfoPO.getMediaId());
                                if (!deviceMediaBindAddressDTOList.isEmpty()) {
                                    //批量保存门口机多媒体资源-服务地址关联信息
                                    batchParams.clear();
                                    for (DeviceMediaBindAddressDTO deviceMediaBindAddressDTO : deviceMediaBindAddressDTOList) {
                                        DeviceMediaGatePO deviceMediaGatePO = new DeviceMediaGatePO();
                                        deviceMediaGatePO.setMediaId(deviceMediaInfoPO.getMediaId());
                                        deviceMediaGatePO.setProjectId(deviceMediaInfoUpdateForBrowserDTO.getProjectId());
                                        deviceMediaGatePO.setDeviceUnique(deviceMediaBindAddressDTO.getDeviceUnique());
                                        deviceMediaGatePO.setCreateTime(deviceMediaInfoPO.getUpdateTime());
                                        deviceMediaGatePO.setUpdateTime(deviceMediaInfoPO.getUpdateTime());
                                        deviceMediaGatePO.setStatus(DataStatusEnum.NORMAL.getType());
                                        batchParams.add(SqlUtil.durableData(deviceMediaGatePO, PlatformConstants.TABLE_SAVE));
                                    }
                                    num += iCommonsDao.batchSaveGate(batchParams);
                                }
                                if (!deviceMediaBindDeviceDTOS.isEmpty()) {
                                    //批量保存围墙机多媒体资源-围墙机关联信息
                                    batchParams.clear();
                                    for (DeviceMediaBindDeviceDTO deviceMediaBindDeviceDTO : deviceMediaBindDeviceDTOS) {
                                        DeviceMediaWallPO deviceMediaWallPO = new DeviceMediaWallPO();
                                        deviceMediaWallPO.setMediaId(deviceMediaInfoPO.getMediaId());
                                        deviceMediaWallPO.setProjectId(deviceMediaInfoUpdateForBrowserDTO.getProjectId());
                                        deviceMediaWallPO.setDeviceUnique(deviceMediaBindDeviceDTO.getDeviceUnique());
                                        deviceMediaWallPO.setSn(deviceMediaBindDeviceDTO.getSn());
                                        deviceMediaWallPO.setCreateTime(deviceMediaInfoPO.getUpdateTime());
                                        deviceMediaWallPO.setUpdateTime(deviceMediaInfoPO.getUpdateTime());
                                        deviceMediaWallPO.setStatus(DataStatusEnum.NORMAL.getType());
                                        batchParams.add(SqlUtil.durableData(deviceMediaWallPO, PlatformConstants.TABLE_SAVE));
                                    }
                                    //保存围墙机关联信息
                                    num += iCommonsDao.batchSaveWall(batchParams);
                                }
                            }
                            com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
                            jsonObject.put("projectId", deviceMediaInfoUpdateForBrowserDTO.getProjectId());
                            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                                    = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_MEDIA, jsonObject, deviceMediaInfoUpdateForBrowserDTO.getProjectId());
                            List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
                            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
                            com.alibaba.fastjson.JSONObject dataJs = new com.alibaba.fastjson.JSONObject();
                            dataJs.put("data", deviceBusinessChangeLogPOS);
                            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                        }
                        inputStream.close();
                        if (num > 0) {
                            return true;
                        }
                        return false;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            LOG.error("OSS回调处理失败！e:" + e.getMessage());
            return false;
        } finally {
            ossClient.shutdown();
        }
        return false;
    }

    /**
     * <desc>
     * 根据多媒体资源投放开始和结束时间推算多媒体资源的发布状态
     * </desc>
     *
     * @param putStartTime 多媒体资源投放开始时间
     * @param putEndTime   多媒体资源投放结束时间
     * @param date         用来比较的基准时间
     * @return 多媒体资源发布状态
     * @author wangzhi
     * @createDate 2018-04-09
     */
    public Integer calculateDeviceMediaPublishStatus(java.util.Date putStartTime, java.util.Date putEndTime, java.util.Date date) {
        // publishStatus 发布状态0-已过期 1-已发布 2-未发布
        if (putStartTime.compareTo(date) > 0) {
            // 投放开始时间大于date，未发布
            return 2;
        }
        if (putStartTime.compareTo(date) < 0 && putEndTime.compareTo(date) > 0) {
            // date在投放时间区间中，已发布
            return 1;
        }
        if (putEndTime.compareTo(date) < 0) {
            // 投放结束时间小于date，已过期
            return 0;
        }
        return null;
    }

    /**
     * <desc>
     * 删除OSS中文件
     * </desc>
     *
     * @param updateNames 文件名称,逗号分隔
     * @return
     * @author Qiang.S
     * @createDate 2018/10/09
     */
    public void deleteFile(String updateNames) {
        OSSClient ossClient = new OSSClient(ALIBABA_OSS_ENDPOINT, ALIBABA_OSS_ACCESSID, ALIBABA_OSS_ACCESSKEY);
        String[] updateName = updateNames.split(",");
        for (String name : updateName) {
            ossClient.deleteObject(ALIBABA_OSS_BUCKET, ALIBABA_OSS_DIR + "/" + name);
        }

    }

    /**
     * <desc>
     * OSS服务验签
     * </desc>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018/07/11
     */
    private static boolean doCheck(String content, byte[] sign, String publicKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            byte[] encodedKey = BinaryUtil.fromBase64String(publicKey);
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
            java.security.Signature signature = java.security.Signature.getInstance("MD5withRSA");
            signature.initVerify(pubKey);
            signature.update(content.getBytes());
            boolean bverify = signature.verify(sign);
            return bverify;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }


    /**
     * <desc>
     * 获取验签相关内容
     * </desc>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018/07/11
     */
    private String executeGet(String url) throws Exception {
        String result = HttpProtocolUtil.doGet(url, new HashMap<>());
        result = result.replace("-----BEGIN PUBLIC KEY-----", "");
        result = result.replace("-----END PUBLIC KEY-----", "");
        return result;
    }

    public boolean downloadFile(String fileName, String filePath) {
        LOG.info("开始下载文件：{}", fileName);
        try {
            OSS ossClient = new OSSClientBuilder().build(ALIBABA_OSS_ENDPOINT, ALIBABA_OSS_ACCESSID, ALIBABA_OSS_ACCESSKEY);
            File file = new File(filePath + File.separator + fileName);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            ossClient.getObject(new GetObjectRequest(ALIBABA_OSS_BUCKET, fileName), file);
            ossClient.shutdown();
            decompressAndMoveFile(file);
            return true;
        } catch (Exception e) {
            LOG.error("下载文件失败，{}", e.getMessage());
            return false;
        }
    }

    /**
     * 解压移动文件
     *
     * @param file
     */
    private void decompressAndMoveFile(File file) {
        //解压目录
        String dep = file.getParent() + File.separator + file.getName().split("\\.")[0];
        File dFile = new File(dep);
        if (!dFile.exists()) {
            dFile.mkdirs();
        }
        UnGZipUtil.decompress(file.getPath(), dep);
        List<File> logFiles = new ArrayList<>();
        //寻找文件复制到外层
        showDirectory(dFile, logFiles);
        for (File f : logFiles) {
            try {
                Files.move(f, new File(dFile + "_" + f.getName()));
            } catch (Exception e) {
                LOG.error("移动文件失败！：{},{}", f.getName(), e.getMessage());
            }
        }
    }

    public static void main(String[] args) throws Exception {

// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAIieKviG1jBpsn";
        String accessKeySecret = "D3epXRB6dtWKpRzUDC5w1ZD7OGU3LX";
        String bucketName = "itlong-tmp";
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        String content = "Hello OSS";
//        PutObjectRequest putObjectRequest = new PutObjectRequest("itlong-kp", "exampleobject.txt", new ByteArrayInputStream(content.getBytes()));
//        ossClient.putObject(putObjectRequest);
        File file = new File("E:\\file\\0000052000000002_20210428141423.tar.gz");
//        ossClient.getObject(new GetObjectRequest(bucketName, "0000052000000002_20210428141423.tar.gz"), file);
        ossClient.shutdown();
    }

    public static void showDirectory(File file, List<File> logFiles) {
        File[] files = file.listFiles();
        for (File a : files) {
            if (a.isFile()) {
                logFiles.add(a);
            }
            if (a.isDirectory()) {
                showDirectory(a, logFiles);
            }
        }
    }
}
